#ifndef DOWNLOADMANAGER_H
#define DOWNLOADMANAGER_H

#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>

#include <QObject>
#include <QFile>
#include <QTimer>
#include <QElapsedTimer>

class DownloadManager : public QObject
{
    Q_OBJECT

public:
    explicit DownloadManager(QObject* parent = nullptr);
    ~DownloadManager();

    enum DownloadState {
        Idle,
        Downloading,
        Paused,
        Completed,
        Error
    };

    // 下载控制
    void startDownload(const QString& url, const QString& filePath);
    void pauseDownload();
    void resumeDownload();
    void cancelDownload();

    // 获取状态信息
    DownloadState getState() const { return m_state; }
    qint64 getDownloadedSize() const { return m_downloadedSize; }
    qint64 getTotalSize() const { return m_totalSize; }
    double getProgress() const;
    QString getSpeed() const;
    QString getErrorMessage() const { return m_errorMessage; }

signals:
    void progressChanged(double percentage, qint64 bytesReceived, qint64 bytesTotal);
    void speedUpdated(const QString& speed);
    void stateChanged(DownloadState state);
    void finished(bool success, const QString& message);
    void errorOccurred(const QString& error);

private slots:
    void onReadyRead();
    void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
    void onFinished();
    void onErrorOccurred(QNetworkReply::NetworkError code);
    void updateSpeed();

private:
    QNetworkAccessManager* m_manager;
    QNetworkReply* m_reply;
    QFile* m_file;
    QTimer* m_speedTimer;
    QElapsedTimer m_downloadTimer;

    QString m_url;
    QString m_filePath;
    qint64 m_totalSize;
    qint64 m_downloadedSize;
    qint64 m_lastDownloadedSize;
    double m_currentSpeed;
    DownloadState m_state;
    QString m_errorMessage;

    void setState(DownloadState state);
    void reset();
    // void cleanup();
    QString formatSpeed(qint64 bytesPerSecond) const;
    QString formatSize(qint64 bytes) const;
    bool openFileForWriting();
    // void handleNetworkError(const QString& error);
};

#endif // DOWNLOADMANAGER_H